package com.leyou.server;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.leyou.common.constants.MQConstants;
import com.leyou.common.exception.pojo.ExceptionEnum;
import com.leyou.common.exception.pojo.LyException;
import com.leyou.common.pojo.PageResult;
import com.leyou.common.utils.BeanHelper;
import com.leyou.item.dto.SpuDTO;
import com.leyou.item.pojo.*;
import com.leyou.mapper.SkuMapper;
import com.leyou.mapper.SpuDetailMapper;
import com.leyou.mapper.SpuMapper;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 商品业务Service
 */
@Service
@Transactional
public class GoodsService extends ServiceImpl <SkuMapper, Sku> {
    @Autowired(required = false)
    private SpuDetailMapper spuDetailMapper;
    @Autowired(required = false)
    private SkuMapper skuMapper;
    @Autowired(required = false)
    private SpuMapper spuMapper;
    @Autowired
    private BrandService brandService;
    @Autowired
    private CategoryService categoryService;
    @Autowired
    private RocketMQTemplate rocketMQTemplate;

    public PageResult<SpuDTO> spuPageQuery(Integer page, Integer rows, String key, boolean saleable) {
        //获取分页对象
        IPage<Spu> iPage = new Page<>(page, rows);
        //分装spu 构造分页条件
        QueryWrapper<Spu> queryWrapper = Wrappers.query();
        if (StringUtils.isNotEmpty(key)) {
            queryWrapper.and(i -> i.like("name", key).or().like("sub_title", key));
        }
        queryWrapper.eq("saleable", saleable);
        //生成返回集合
        iPage = spuMapper.selectPage(iPage, queryWrapper);
        List<Spu> records = iPage.getRecords();
        List<SpuDTO> spuDTOList = BeanHelper.copyWithCollection(records, SpuDTO.class);
        //封装分类名称和品牌名称
        getCategoryNameAndBrandName(spuDTOList);
        //分装集合
        PageResult<SpuDTO> pageResult = new PageResult<>(iPage.getTotal(), iPage.getPages(), spuDTOList);
        //返回pageResult
        return pageResult;
    }

    /**
     * 封装分类名称和品牌名称
     *
     * @param spuDTOList
     */
    public void getCategoryNameAndBrandName(List<SpuDTO> spuDTOList) {
        //分装品牌名称
        spuDTOList.forEach(spuDTO -> {
            //分装品牌名称
            Brand brand = brandService.findBrandById(spuDTO.getBrandId());
            spuDTO.setBrandName(brand.getName());
            //分装分类名称
            List<Category> categoriesByCids = categoryService.findCategoriesByCids(Arrays.asList(spuDTO.getCid1(), spuDTO.getCid2(), spuDTO.getCid3()));
            //把名称转换
            String cateName = categoriesByCids.stream().map(category -> category.getName()).collect(Collectors.joining("/"));
            spuDTO.setCategoryName(cateName);

        });
    }

    public void saveGoods(SpuDTO spuDTO) {
        try {
            //1.保存Spu表
            //拷贝数据
            Spu spu = BeanHelper.copyProperties(spuDTO, Spu.class);
            spu.setSaleable(false);
            spuMapper.insert(spu);
            //2.保存spu_detail表
            SpuDetail spuDetail = spuDTO.getSpuDetail();
            spuDetail.setSpuId(spu.getId());
            spuDetailMapper.insert(spuDetail);
            //3.保存sku表
            List<Sku> skus = spuDTO.getSkus();
            skus.forEach(sku -> {
                sku.setSpuId(spu.getId());
            });
            //批量保存
            saveBatch(skus);
        } catch (Exception e) {
            e.printStackTrace();
            throw new LyException(ExceptionEnum.INSERT_OPERATION_FAIL);
        }

    }

    public void updateSaleable(Long id, Boolean saleable) {
        try {
            Spu spu = new Spu();
            spu.setId(id);
            spu.setSaleable(saleable);
            //1）根据saleable确定主题标签

            String tagname=saleable ? MQConstants.Tag.ITEM_UP_TAG:MQConstants.Tag.ITEM_DOWN_TAG;

            String destination=MQConstants.Topic.ITEM_TOPIC_NAME+":"+tagname;
            //2)发送消息给RocketMQ
            /**
             * 参数一：目的地。只写Topic，也可以写Topic:Tag
             * 参数二：消息内容
             */
            rocketMQTemplate.convertAndSend(destination,id);

        } catch (Exception e) {
            e.printStackTrace();
            throw new LyException(ExceptionEnum.UPDATE_OPERATION_FAIL);
        }
    }

    public List<Sku> findSkusBySpuId(Long id) {
        Sku sku = new Sku();
        sku.setSpuId(id);
        QueryWrapper<Sku> query = Wrappers.query(sku);
        List<Sku> spus = skuMapper.selectList(query);
        if (CollectionUtils.isEmpty(spus)){
            throw new LyException(ExceptionEnum.GOODS_NOT_FOUND);
        }
        return spus;
    }
    /**
     * 查询spuDtail
     */
    public SpuDetail findSpuDetailBySpuId(Long id) {
        QueryWrapper<SpuDetail> query = Wrappers.query();
         query.eq("id",id);
        SpuDetail spuDetail = spuDetailMapper.selectById(id);
        if(spuDetail==null){
            throw new LyException(ExceptionEnum.GOODS_NOT_FOUND);
        }
        return  spuDetail;
    }

    public SpuDTO findSpuDTOBySpuId(Long id) {
        //分装spu
        Spu spu = spuMapper.selectById(id);
        SpuDTO spuDTO = BeanHelper.copyProperties(spu, SpuDTO.class);
        //分装spuDetail
        SpuDetail spuDetail = spuDetailMapper.selectById(id);
        spuDTO.setSpuDetail(spuDetail);
        //分装sku
        List<Sku> skus = findSkusBySpuId(id);
        spuDTO.setSkus(skus);
        return spuDTO;
    }

    public List<Sku> findSkuByIds(List<Long> ids) {
        List<Sku> skus = skuMapper.selectBatchIds(ids);
        if (CollectionUtils.isEmpty(skus)){
            throw new LyException(ExceptionEnum.CARTS_NOT_FOUND);
        }
        return skus;
    }
}
